﻿using System;
using System.Drawing;
using System.Windows.Forms;

using dbe.FoundationLibrary.Core.Win32.API;

namespace UCTT.NetFx
{
    public partial class Form9 : Form
    {
        #region    变量&常量 start
        private int x, y;
        private float scale;
        private Bitmap _bit;
        private IntPtr _bitPtr;
        #endregion 变量&常量 end

        #region    构造&析构 start

        public Form9()
        {
            InitializeComponent();
        }
        #endregion 构造&析构 end

        #region    事件处理 start
        private void btn_SelectImage_Click(object sender, EventArgs e)
        {
            try
            {
                var openFileDialog = new OpenFileDialog();
                openFileDialog.Filter = "图片文件|*.jpg;*.jpeg;*.png;*.bmp|所有文件|*.*";
                openFileDialog.Title = "选择图片";

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    string filePath = openFileDialog.FileName;
                    _bit = new Bitmap(filePath);
                    _bitPtr = _bit.GetHbitmap();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btn_Start_Click(object sender, EventArgs e)
        {
            btn_SelectImage.Enabled = false;
            btn_Start.Enabled = false;
            //btn_Stop.Enabled = false;
            timer1.Start();
            btn_Stop.Enabled = true;
        }

        private void btn_Stop_Click(object sender, EventArgs e)
        {
            btn_Start.Enabled = false;
            btn_Stop.Enabled = false;
            timer1.Stop();
            btn_Start.Enabled = true;
            btn_SelectImage.Enabled = true;
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (_bit == null) return;
            if (_bitPtr == IntPtr.Zero) return;
            var startTime = DateTime.Now;
            var prefix = string.Empty;
            if (radbtn_GDIPlus.Checked)
            {
                DrawImage(e);
                prefix = "GDI+";
            }
            else if (radbtn_GDIApi.Checked)
            {
                DrawImage2(e);
                prefix = "GDI_Api";
            }
            var endTime = DateTime.Now;
            var timeSpan = endTime - startTime;
            txt_Result.AppendText($"{prefix} 耗时{timeSpan.TotalMilliseconds}ms\n");
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            pictureBox1.Invalidate();
        }
        #endregion 事件处理 end

        #region    私有函数 start
        private void DrawImage(PaintEventArgs e)
        {
            BufferedGraphicsContext GraphicsContext = BufferedGraphicsManager.Current;
            BufferedGraphics myBuffer = GraphicsContext.Allocate(e.Graphics, e.ClipRectangle);
            Graphics g = myBuffer.Graphics;
            Bitmap bitmap = _bit;
            int destWidth = pictureBox1.Width;
            int destHeight = pictureBox1.Height;
            int srcWidth = _bit.Width;
            int srcHeight = _bit.Height;
            float scaleX = (float)destWidth / srcWidth;
            float scaleY = (float)destHeight / srcHeight;
            float scale = Math.Min(scaleX, scaleY);
            int width = (int)(srcWidth * scale);
            int height = (int)(srcHeight * scale);
            x = (destWidth - width) >> 1;
            y = (destHeight - height) >> 1;
            g.DrawImage(bitmap, x, y, width, height);
            myBuffer.Render(e.Graphics);
            g.Dispose();
            myBuffer.Dispose();
        }

        

        private void DrawImage2(PaintEventArgs e)
        {
            BufferedGraphicsContext GraphicsContext = BufferedGraphicsManager.Current;
            BufferedGraphics myBuffer = GraphicsContext.Allocate(e.Graphics, e.ClipRectangle);
            Graphics g = myBuffer.Graphics;
            IntPtr hdc = g.GetHdc();

            float scaleX = (float)pictureBox1.Width / _bit.Width;
            float scaleY = (float)pictureBox1.Height / _bit.Height;
            float scale = Math.Min(scaleX, scaleY);
            int w = (int)(_bit.Width * scale);
            int h = (int)(_bit.Height * scale);
            x = (pictureBox1.Width - w) >> 1;
            y = (pictureBox1.Height - h) >> 1;
            Gdi32.DrawImage(hdc, _bitPtr, _bit.Width, _bit.Height, x, y, scale);
            g.ReleaseHdc(hdc);
            myBuffer.Render(e.Graphics);
            g.Dispose();
            myBuffer.Dispose();
        }
        #endregion 私有函数 end
    }
}